/*
 Copyright 2011 Dario Seitel, Sebastian Mayer. All rights reserved.

 Redistribution and use in source and binary forms, with or without modification, are
 permitted provided that the following conditions are met:

 1. Redistributions of source code must retain the above copyright notice, this list of
 conditions and the following disclaimer.

 2. Redistributions in binary form must reproduce the above copyright notice, this list
 of conditions and the following disclaimer in the documentation and/or other materials
 provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 The views and conclusions contained in the software and documentation are those of the
 authors and should not be interpreted as representing official policies, either expressed
 or implied, of <copyright holder>.
 */

#ifndef ENTITY_H_
#define ENTITY_H_

#include <boost/archive/text_oarchive.hpp>
#include "../../output/Renderer.h"

#define PROP_COLLISION_TERRAIN 1
#define PROP_COLLISION_PLAYER 2
#define PROP_DESTRUCTIBLE 4

/**
 * This is the base class for all elements of the game world.
 */
class Entity {
public:
	Entity();
	Entity(float x, float y);
	virtual ~Entity();

	virtual float getX();
	virtual float getY();
	virtual void setX(float x);
	virtual void setY(float y);
	virtual float getBoundingBoxHalfWidth();
	virtual float getBoundingBoxHalfHeight();
	virtual void setBoundingBoxHalfWidth(float boundingBoxHalfWidth);
	virtual void setBoundingBoxHalfHeight(float boundingBoxHalfHeight);
	/**
	 * Toggles the given property on/off.
	 * @see PROP_ constants
	 * @param property the property to be toggled
	 */
	virtual void toggleProperty(int property);
	/**
	 * @see PROP_ constants
	 * @param property the property to be checked
	 * @return true if the given property is enabled, false otherwise
	 */
	virtual bool hasProperty(int property);
	/**
	 * @see PROP_COLLISION_ constants
	 * @param collisionType
	 */
	virtual void setCollisionType(int collisionType);
	/**
	 * @see PROP_COLLISION_ constants
	 * @see toggleProperty()
	 * @return the collision type set for this entity. Other entities that have
	 * the same type set as a property will collide with this entity.
	 */
	virtual int getCollisionType();
	/**
	 * Called when this entity has to be rendered.
	 */
	virtual void render() = 0;
	/**
	 * Used for initializing values that are identical for all instances of the
	 * specific implementation of this class, e.g. bounding box size, properties, ...
	 * Needs to be called from all constructors!
	 */
	virtual void init() = 0;
	virtual void tick();

private:
	float x, y, boundingBoxHalfWidth, boundingBoxHalfHeight;
	int propertyMask, collisionType;

	friend class boost::serialization::access;
	template <typename Archive>
	void serialize(Archive &ar, const unsigned int version)
	{
		ar & x & y;
	}
};

#endif /* ENTITY_H_ */
